﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PropertySetViewModel.cs" >
//   J. Prinz
// </copyright>
// <summary>
//   View Model used for Representation of an InternalElement <see cref="InternalElementType" /> which is assigned with a PropertySet RoleClass
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace AutomationMLMapper.ViewModels.CAEXObjectViewModels
{
    using System;

    using CAEX_ClassModel;

    using AutomationMLMapper.AutomationML.Extensions;
    using AutomationMLMapper.ViewModels.CAEXObjectCollectionViewModels;

    /// <summary>
    ///   View Model used for Representation of an InternalElement <see cref="InternalElementType" /> which is assigned with a PropertySet RoleClass
    /// </summary>
    public class PropertySetViewModel : InternalElementViewModel
    {
        #region Constructors and Destructors

        /// <summary>
        ///  Initializes a new instance of the <see cref="PropertySetViewModel"/> class. 
        /// </summary>
        /// <param name="element">
        /// a CAEX - InternalElement which has an assigned RoleClass, derived from PropertySet
        /// </param>
        public PropertySetViewModel(InternalElementType element)
            : base(element)
        {
            this.AttributesCollection = new AttributeCollectionViewModel(this);
            this.MappingObjectCollection = new MappingObjectCollectionViewModel(this);
            this.MappingObjectCollection.AllowCommand += this.MappingObjectCollectionAllowCommand;
        }

        #endregion

        #region Public Properties

        /// <summary>
        ///   DisplayName of the CAEX-Element in the UI used in Headers and Labels
        /// </summary>
        public static new string DisplayName
        {
            get
            {
                return "PropertySet";
            }
        }

        /// <summary>
        ///   The Collection of Attributes <see cref="AttributeViewModel" /> of the PropertySet
        /// </summary>
        public AttributeCollectionViewModel AttributesCollection { get; set; }

        /// <summary>
        ///   The Collection of MappingObjects <see cref="MappingTypeViewModel" /> for the PropertySet
        /// </summary>
        public MappingObjectCollectionViewModel MappingObjectCollection { get; set; }

        /// <summary>
        ///   The Owner of the InternalElement-PropertySet
        /// </summary>
        public SystemUnitClassViewModel Owner { get; set; }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// the AddMethod will add an additional AttributeName Mapping Object
        /// </summary>
        /// <param name="caexObjectType">
        /// </param>
        /// <returns>
        /// The AutomationMLMapper.ViewModels.ICAEXObject. 
        /// </returns>
        public override ICAEXObject AddElement(Type caexObjectType)
        {
            if (caexObjectType == typeof(MappingTypeViewModel))
            {
                var mappingObject = !this.CaexObject.MappingObject.Exists
                                        ? this.CaexObject.New_MappingObject()
                                        : this.CaexObject.MappingObject[0];

                var attnm =
                    mappingObject.New_AttributeNameMapping(
                        ((AttributeViewModel)this.Owner.AttributesCollection.View.CurrentItem).Name, 
                        ((AttributeViewModel)this.AttributesCollection.View.CurrentItem).Name);

                base.AddElement(caexObjectType);

                return new MappingTypeViewModel(attnm);
            }

            return null;
        }

        /// <summary>
        ///   the LoadMethod for PropertySet will load all attributes and mappingObjects
        /// </summary>
        public override void LoadCaexToRepresentationModel()
        {
            base.LoadCaexToRepresentationModel();

            if (this.CaexObject.RoleRequirements.Exists)
            {
                foreach (var attribute in this.CaexObject.RoleRequirements[0].GetOwnAndDerivedAttributes())
                {
                    var attributeRepresentation = new AttributeViewModel(attribute);
                    attributeRepresentation.LoadCaexToRepresentationModel();
                    this.AttributesCollection.Elements.Add(attributeRepresentation);
                }
            }

            foreach (MappingType mappingObject in this.CaexObject.MappingObject)
            {
                foreach (AttributeNameMappingType attm in mappingObject.AttributeNameMapping)
                {
                    var mappingRepresentation = new MappingTypeViewModel(attm);

                    mappingRepresentation.LoadCaexToRepresentationModel();
                    this.MappingObjectCollection.Elements.Add(mappingRepresentation);
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// EventHandler for the AddCommand of the MappingCollection <see cref="MappingObjectCollection"/> 
        ///   The Add command can only be executed if there is a current item selected in the AttributesCollection <see cref="AttributesCollection"/> od the
        ///   PropertySet and also in the AttributesCollection of the Owner <see cref="Owner"/>
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="commandArgs">
        /// </param>
        private void MappingObjectCollectionAllowCommand(
            object sender, CollectionCommandEventArgs<MappingTypeViewModel> commandArgs)
        {
            if (commandArgs.Command == this.MappingObjectCollection.AddCommand)
            {
                commandArgs.AllowCommand = this.MappingObjectCollection.Elements.Count == 0
                                           && this.AttributesCollection.View.CurrentItem is AttributeViewModel
                                           && this.Owner != null
                                           && this.Owner.AttributesCollection.View.CurrentItem is AttributeViewModel;
            }
        }

        #endregion
    }
}